home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / fortify.lha / fortify.doc < prev    next >
Encoding:
Text File  |  1995-02-03  |  17.4 KB  |  407 lines

  1.          Fortify - fortified memory allocation shell for C and C++
  2.          ---------------------------------------------------------
  3.                         written by Simon P. Bullen
  4.                                Cybergraphic
  5.                                
  6.                            Release 1.0, 2/2/1995
  7.  
  8.  
  9.  
  10.  
  11.            This  software  is  not  public domain.  All material in
  12.        this  archive  is  ©  Copyright  1995 Simon P.  Bullen.  The
  13.        software  is freely distrubtable, with the condition that no
  14.        more than a nominal fee is charged for media.  Everything in
  15.        this  distrubution  must  be  kept  together,  in  original,
  16.        unmodified form.
  17.            The files may be modified for your own personal use, but
  18.        modified files may not be distributed.
  19.            The material is provided "as is" without warranty of any
  20.        kind.  The author accepts no responsibilty for damage caused
  21.        by this software.
  22.  
  23.  
  24.  
  25.                        email: sbullen@ozemail.com.au
  26.                        snail: Simon P. Bullen
  27.                               PO BOX 12138
  28.                               A'Beckett St
  29.                               Melbourne 3000
  30.                               Australia
  31.  
  32.  
  33.  
  34.     CONTENTS
  35.     --------
  36.     Your archive should have the following files:
  37.  
  38.                fortify.c       
  39.                fortify.doc     
  40.                fortify.h       
  41.                test.c          
  42.                ufortify.h    
  43.                ufortify.hpp
  44.                zfortify.cpp
  45.                zfortify.hpp
  46.                ztest.cpp     
  47.  
  48.  
  49.  
  50.  
  51.     OVERVIEW
  52.     --------        
  53.     Fortify  is  a  descendant of a library I wrote way back in 1990 called
  54. SafeMem.   It is a (fortified) shell for memory allocations.  It works with
  55. the  malloc/free family of functions, as well as new/delete in C++.  It can
  56. be  adapted  to  most  memory management functions; the original version of
  57. SafeMem  worked  only  with  the  Amiga's AllocMem/FreeMem.  I haven't been
  58. writing  much  Amiga  specific  software  lately,  so  the Amiga version of
  59. Fortify is way out of date, hence it's absense from this archive.
  60.  
  61.     Fortify  is  designed  to  detect  bad things happening, or at the very
  62. least encourage intermittent problems to occur all the time.  It is capable
  63. of  detecting  memory  leaks,  writes  beyond and before memory blocks, and
  64. breaks  software  that  relies  on  the  state of uninitialized memory, and
  65. software that uses memory after it's been freed.
  66.  
  67.     It  works  by  allocating  extra  space on each block.  This includes a
  68. private  header (which is used to keep track of Fortify's list of allocated
  69. memory),  and  two  "fortification"  zones  or sentinals (which are used to
  70. detect writing outside the bound of the user's memory).
  71.  
  72.  
  73.  
  74.  
  75.     Fortify VERSUS ZFortify
  76.     -----------------------
  77.     Fortify  provides  fortification  for malloc/realloc/free, and ZFortify
  78. provides  fortifications  for  new/delete.   It  is  possible  to  use both
  79. versions  in  the one program, if you are mixing C and C++.  Just make sure
  80. (as  you  already  should  be)  that you never free() memory you new'd, and
  81. other such illegal mismatching.
  82.     (Why _Z_ fortify? It's a long story...)
  83.  
  84.  
  85.  
  86.     Fortify INSTALLATION (C)
  87.     ------------------------
  88.     To use Fortify, each source file will need to #include "fortify.h".  To
  89. enable  Fortify,  define the symbol FORTIFY.  If FORTIFY is not defined, it
  90. will compile away to nothing.  If you do not have stdout available, you may
  91. wish  to  set  an  alternate output function.  See Fortify_SetOutputFunc(),
  92. below.
  93.     You will also need to link in fortify.o
  94.  
  95.  
  96.  
  97.  
  98.     ZFortify INSTALLATION (C++)
  99.     ---------------------------
  100.     The  minimum  you  need  to  do  for  ZFortify  is to define the symbol
  101. ZFORTIFY,  and  link  zfortify.o.   Each  source  file  should also include
  102. "zfortify.hpp",  but  this  isn't  strictly  necessary.   If a file doesn't
  103. #include  "Fortify.hpp",  then  it's  allocations  will still be fortified,
  104. however  you  will  not  have  any source-code details in any of the output
  105. messages (this will be the case for all libraries, etc, unless you have the
  106. source for the library and can recompile it with Fortify).
  107.     If  you  do not have stdout available, you may wish to set an alternate
  108. output    function,    or    turn    on    the    AUTOMATIC_LOGFILE.    See
  109. ZFortify_SetOutputFunc() and AUTOMATIC_LOGFILE, below.
  110.  
  111.  
  112.  
  113.  
  114.     COMPILE TIME CUSTOMIZATIONS
  115.     ---------------------------
  116.     The  files "ufortify.h" and "ufortify.hpp" contain a number of #defines
  117. that  you  can use to customize Fortify's behavior.  
  118.  
  119.  
  120.     #define ZFORTIFY_PROVIDE_ARRAY_NEW
  121.  
  122.     Some C++ compilers have a separate operator for newing arrays.  If your
  123. compiler  does,  you  will  need to define this symbol.  If you are unsure,
  124. dont  worry  about  it too much, your program won't compile or link without
  125. the  correct setting.  GCC 2.6.3 and Borland C++ 4.5 both need this symbol.
  126. Microsoft C++ 1.5 and SAS 6.5 C++ both dont.
  127.  
  128.  
  129.     #define FORTIFY_STORAGE
  130.  
  131.     #define ZFORTIFY_STORAGE
  132.  
  133. You  can  use  this  to apply a storage type to all of Fortify's exportable
  134. functions.   If  you  are putting Fortify in an export library for example,
  135. you may need to put __export here, or some such rubbish.
  136.  
  137.  
  138.     #define FORTIFY_BEFORE_SIZE       32
  139.     #define FORTIFY_BEFORE_VALUE    0xA3
  140.                       
  141.     #define FORTIFY_AFTER_SIZE        32
  142.     #define FORTIFY_AFTER_VALUE     0xA5
  143.  
  144.     #define ZFORTIFY_BEFORE_SIZE      32
  145.     #define ZFORTIFY_BEFORE_VALUE   0xA3
  146.                       
  147.     #define ZFORTIFY_AFTER_SIZE       32
  148.     #define ZFORTIFY_AFTER_VALUE    0xA5
  149.  
  150.     These  values  define  how  much  "fortification" is placed around each
  151. memory  block you allocate.  Fortify will place _BEFORE_SIZE bytes worth of
  152. memory  right  before  your  allocation  block, and _AFTER_SIZE bytes worth
  153. after your allocation block, and these will be initialized to _BEFORE_VALUE
  154. and  _AFTER_VALUE  respectively.   If your program then accidentally writes
  155. too  far  beyond the end of the block, for example, Fortify will be able to
  156. detect this (so long as you didn't happen to write in _AFTER_VALUE!).
  157.  
  158.     If  you  don't  want  these  fortifications  to be allocated, specify a
  159. _SIZE of 0.  Note that the _VALUE parameters are 8 bits.
  160.  
  161.  
  162.  
  163.     #define FILL_ON_MALLOC
  164.     #define FILL_ON_MALLOC_VALUE    0xA7
  165.  
  166.     #define FILL_ON_NEW
  167.     #define FILL_ON_NEW_VALUE       0xA7
  168.  
  169.     Programs  often  rely  on  uninitialized  memory  being  certain values
  170. (usually  0).   If  you define FILL_ON_NEW, all memory that you new will be
  171. initialized to FILL_ON_NEW_VALUE, which you should define to be some horrid
  172. value  (definately  NOT  0).   This  will encourage all code that relies on
  173. uninitialized memory to behave rather differently when Fortify is running.
  174.  
  175.  
  176.  
  177.     #define FILL_ON_FREE
  178.     #define FILL_ON_FREE_VALUE       0xA9 
  179.  
  180.     #define FILL_ON_DELETE
  181.     #define FILL_ON_DELETE_VALUE     0xA9 
  182.  
  183.     Programmers  often  try to use memory after they've freed it, which can
  184. sometimes  work  (so long as noboby else has modified the memory before you
  185. look  at  it), but is incredibly dangerous and definately bad practice.  If
  186. FILL_ON_DELETE  is  defined,  all  memory you free will be stomped out with
  187. FILL_ON_DELETE_VALUE,  which  ensures that any attempt to read freed memory
  188. will give incorrect results.
  189.  
  190.  
  191.  
  192.     #define CHECK_ALL_MEMORY_ON_MALLOC
  193.     #define CHECK_ALL_MEMORY_ON_FREE
  194.  
  195.     #define CHECK_ALL_MEMORY_ON_NEW 
  196.     #define CHECK_ALL_MEMORY_ON_DELETE
  197.  
  198.     CHECK_ALL_MEMORY_ON...   means  that for every single memory allocation
  199. or  deallocation,  every  single block of memory will be checked.  This can
  200. considerably  slow  down  programs  if  you  have  a large number of blocks
  201. allocated.   You would normally only need to turn this on if you are trying
  202. to pinpoint where a corruption was occurring.
  203.     A  block  of  memory  is  always  checked  when  it  is  freed,  so  if
  204. CHECK_ALL...    isn't   turned  on,  corruptions  will  still  be  detected
  205. eventually.
  206.     You  can  also  force  Fortify  to  check  all  memory  with  a call to
  207. Fortify_CheckAllMemory().   If you have a memory corruption you can't find,
  208. sprinkling these through the suspect code will help narrow it down.
  209.  
  210.  
  211.  
  212.     #define PARANOID_FREE
  213.  
  214.     #define PARANOID_DELETE
  215.  
  216.     PARANOID_...   -  This means that zFortify traverses the memory list to
  217. ensure  the  memory  you are about to free was really allocated by it.  You
  218. probably  only need this in extreme circumstances.  Not having this defined
  219. will  still  trap  attempts  to  free  memory that wasn't allocated, unless
  220. someone is deliberately trying to fool zFortify.
  221.     Paranoid  mode adds considerable overhead to freeing memory, especially
  222. if  you  are  freeing things in the same order you allocated them (Paranoid
  223. mode  is most efficient if you are freeing things in the reverse order they
  224. were allocated).
  225.  
  226.  
  227.  
  228.     #define WARN_ON_MALLOC_FAIL
  229.     #define WARN_ON_ZERO_MALLOC
  230.     #define WARN_ON_FALSE_FAIL
  231.     #define WARN_ON_UNSIGNED_LONG_OVERFLOW
  232.  
  233.     #define WARN_ON_NEW_FAIL
  234.     #define WARN_ON_ZERO_NEW
  235.  
  236.     These defines enable the output of warning that aren't strictly errors,
  237. but can be useful to determine what lead to a program crashing.
  238.     WARN_ON_NEW_FAIL causes a debug to be issued whenever new fails.
  239.     WARN_ON_ZERO_NEW  causes  a debug to be issued whenever a new of a zero
  240. byte object is attempted.  This is fairly unlikely in C++, and is much more
  241. likely when using malloc().
  242.     WARN_ON_FALSE_FAIL  causes  a  debug to be issued when a new is "false"
  243. failed.  ZSee Fortify_SetNewFailRate() for more information.
  244.     WARN_ON_UNSIGNED_LONG_OVERFLOW causes Fortify to check for breaking the
  245. 32  bit  limit.   This  was  more of a problem in 16-bit applications where
  246. breaking  the  16  bit  limit  was  much  more likely.  The problem is that
  247. Fortify  adds  a small amount of overhead to a memory block; so in a 16-bit
  248. size_t  environment,  if you tried to allocate 64K, Fortify would make that
  249. block bigger than 64K and your allocation would fail due to the presence of
  250. Fortify.   With size_t being 32 bits for all environments worth programming
  251. in,  this  problem  is  extremely  unlikely  (Unless you plan to allocate 4
  252. gigabytes).
  253.  
  254.  
  255.     #define AUTOMATIC_LOG_FILE
  256.     #define LOG_FILENAME            "fortify.log"
  257.     #define FIRST_ERROR_FUNCTION    
  258.  
  259.     If  AUTOMATIC_LOG_FILE  is  defined  (C++ version /ZFortify only), then
  260. Fortify will be automatically started for you, Fortify messages sent to the
  261. named  log  file, and a list of unfreed memory dumped on termination (where
  262. the  log  file  will  be  automatically  closed for you.  If no Fortify was
  263. output,  the log file will not be altered.  There are timestamps in the log
  264. file to ensure you're reading the correct messages.
  265.     FIRST_ERROR_FUNCTION  will  be  called  upon  generation  of  the first
  266. Fortify  message,  so  that  the  user  can  tell a Fortify report has been
  267. generated.   Otherwise,  Fortify  would quietly write all this useful stuff
  268. out to the log file, and no-one would know to look there!
  269.                                            
  270.  
  271.  
  272.     #define FORTIFY_LOCK()
  273.     #define FORTIFY_UNLOCK()
  274.  
  275.     #define ZFORTIFY_LOCK()
  276.     #define ZFORTIFY_UNLOCK()
  277.  
  278.     In  a  multi-threaded  environment,  we need to arbitrate access to the
  279. foritfy  memory  list.   This is what ZFORTIFY_LOCK() and ZFORTIFY_UNLOCK()
  280. are  used  for.   The  calls  to ZFORTIFY_LOCK() and ZFORTIFY_UNLOCK() must
  281. nest.  If no two threads/tasks/processes will be using the same Fortify at
  282. the  same  time,  then  ZFORTIFY_LOCK() and ZFORTIFY_UNLOCK() can safely be
  283. #defined away to nothing.
  284.  
  285.  
  286.  
  287.  
  288.     RUN TIME CONTROL
  289.     ----------------
  290.     Fortify  can  also  be  controlled  at  run  time  with  a  few special
  291. functions,  which  compile away to nothing if FORTIFY isn't defined, and do
  292. nothing  if  Fortify  has  been  disabled  with  Fortify_Disable().   These
  293. functions  all  apply  to  ZFortify  as  well (The ZFortify versions have a
  294. ZFortify_ prefix, of course).
  295.  
  296.     Fortify_Disable()  -  This  function  provides  a  mechanism to disable
  297. Fortify  without  recompiling  all  the sourcecode.  It can only be called,
  298. though,  when  there  is  no  memory on the Fortify list.  (Ideally, at the
  299. start  of  the  program before any memory has been allocated).  If you call
  300. this  function  when  there IS memory on the Fortify list, it will issue an
  301. error, and Fortify will not be disabled.
  302.   
  303.     Fortify_SetOutputFunc(Fortify_OutputFuncPtr Output) - Sets the function
  304. used  to  output  all error and diagnostic messages by Fortify.  The output
  305. function takes a single (const char *) argument, and must be able to handle
  306. newlines.  The function returns the old pointer.
  307.     The  default output func is a printf() to stdout.  Unless you are using
  308. AUTOMATIC_LOG_FILE, where the default is to output to the log file.
  309.  
  310.     Fortify_SetNewFailRate(int  Percent)  - Fortify will make a new attempt
  311. "fail" this "Percent" of the time, even if the memory IS available.  Useful
  312. to  "stress-test"  an  application.   Returns the old value.  The fail rate
  313. defaults to 0.
  314.   
  315.  
  316.  
  317.     DIAGNOSTIC FUNCTIONS
  318.     --------------------
  319.     Fortify also provides some additional diagnostic functions which can be
  320. used  to  track  down  memory  corruption  and memory leaks.  If Fortify is
  321. disabled,  these functions do nothing.  If calling these functions directly
  322. from  a debugger, remember to add the "char *file" and "unsigned long line"
  323. paramters  to  each  of  the  calls.  (The ZFortify versions have a
  324. ZFortify_ prefix, of course).
  325.    
  326.     Fortify_CheckPointer(void *uptr) - Returns true if the uptr points to a
  327. valid piece of Fortify'd memory.  The memory must be on Fortify's list, and
  328. it's  sentinals must be in tact.  If anything is wrong, an error message is
  329. issued (Note - if Fortify is disabled, this function always returns true).
  330.   
  331.     Fortify_CheckAllMemory() - Checks the sentinals of all malloc'd memory.
  332. Returns  the  number  of blocks that failed.  (If Fortify is disabled, this
  333. function always returns 0).
  334.   
  335.     Fortify_OutputAllMemory()  -  Outputs  the  entire  list  of  currently
  336. allocated  memory.   For  each  block  is  output  it's  Address, Size, the
  337. SourceFile and Line that allocated it, and the fortify scope from within it
  338. was  allocated.   If  there is no memory on the list, this function outputs
  339. nothing.   It  returns the number of blocks on the list, unless Fortify has
  340. been disabled, in which case it always returns 0.
  341.  
  342.     Fortify_DumpAllMemory(scope)   -   Just  like  Fortify_OutputAllMemory,
  343. except  all memory inside the given scope is output, and a hex dump of each
  344. block is included in the output.
  345.  
  346.     Fortify_EnterScope()  -  enters  a level of fortify scope.  Returns the
  347. new scope level.
  348.  
  349.     Fortify_LeaveScope()  - leaves a level of fortify scope, it also prints
  350. a  dump  of  all memory allocated within the scope being left.  This can be
  351. very  useful  in tracking down memory leaks in a part of a program.  If you
  352. place  a  EnterScope/LeaveScope  pair around a set of functions that should
  353. have  no memory allocated when it's done, Fortify will let you know if this
  354. isn't the case.
  355.  
  356.  
  357.     PROBLEMS WITH THE new AND delete MACROS
  358.     ---------------------------------------
  359.     Due  to  limitations  of  the  preprocessor,  getting caller sourcecode
  360. information  isn't as easy as it is for malloc() and free().  The macro for
  361. "new" which adds this information onto the new call causes syntax errors if
  362. you  try  to  declare  a  custom new operator.  The actual Fortifying works
  363. fine, it's just the macro expansion which causes problems.
  364.     If  this  happens, you will need to place #undef's and #define's around
  365. the   offending   code   (sorry).   Alternatively,  you  can  not  #include
  366. "zfortify.hpp"  for  the  offending  file.   But  remember that none of the
  367. allocation done in that file will have sourcecode information.
  368.  
  369. eg.
  370. #undef new 
  371. void *X::operator new(size_t) { return malloc(size_t); }
  372. #define new Fortify_New
  373.  
  374.  
  375.     Due  to a limitation with delete, Fortify has limited information about
  376. where  delete  is  being called called from, and so the the line and source
  377. information will often say "delete.0".  If a delete is occuring from within
  378. another  delete,  Fortify will always endeavour to report the highest level
  379. delete as the caller.
  380.  
  381.     It  should  be  possible to replace the "new.0" and "delete.0" with the
  382. return  address  of the function, which would be useful when in a debugger,
  383. but  this  would  be  highly  architecture dependant, so I leave that as an
  384. exercise for the students :-).
  385.  
  386.  
  387.  
  388.     WHEN TO USE FORTIFY
  389.     -------------------
  390.     The  simple  answer  to  this  is  "All The Time".  You should never be
  391. without  Fortify  when you're actually developing software.  It will detect
  392. your  bugs _as_you_write_them_, which makes them a lot easier to find.  One
  393. programmer  who  recently  started using Fortify when he had a very strange
  394. memory  problem,  spent  at  least 3 or 4 days tracking down _other_ memory
  395. corruption  bugs that he wasn't even aware of before the program would stay
  396. up  long enough to get to his original problem.  If he'd been using Fortify
  397. from the beginning, this wouldn't have been a problem.
  398.     Leave  fortify  enabled  until  the  final  test  and  release  of your
  399. software.   You  probably  won't  want  some of the slower options, such as
  400. CHECK_ALL_MEMORY_ON_FREE,  and  PARANOID_FREE.  With the exception of those
  401. options,  Fortify doesn't have a great deal of overhead.  If posing a great
  402. problem,  this  overhead can be greatly reduced by cutting down on the size
  403. of  the  fortifications, and turning off the pre/post fills, but each thing
  404. you  turn  off gives fortify less information to work with in tracking your
  405. bugs.
  406.  
  407.